﻿using System;
using System.Collections;
using System.Text;
using ActiproSoftware.SyntaxEditor;

namespace WindowsUserControl.Codes
{
    /// <summary>
    /// Represents a Simple language compilation unit.
    /// </summary>
    public class CompilationUnit : AstNode, ICompilationUnit, ISemanticParseData
    {

        private System.String sourceKey;

        private bool hasLanguageTransitions;
        private ArrayList syntaxErrors;

        /// <summary>
        /// Gets the context ID for the collection of functions.
        /// </summary>
        public const byte FunctionContextID = AstNode.AstNodeContextIDBase;

        /// <summary>
        /// Gets the minimum context ID that should be used in your code for AST nodes inheriting this class.
        /// </summary>
        /// <remarks>
        /// Base all your context ID constants off of this value.
        /// </remarks>
        protected const byte CompilationUnitContextIDBase = AstNode.AstNodeContextIDBase + 1;

        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // OBJECT
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes a new instance of the <c>CompilationUnit</c> class. 
        /// </summary>
        public CompilationUnit() { }

        /// <summary>
        /// Initializes a new instance of the <c>CompilationUnit</c> class. 
        /// </summary>
        /// <param name="textRange">The <see cref="TextRange"/> of the AST node.</param>
        public CompilationUnit(TextRange textRange) : base(textRange) { }

        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Accepts the specified visitor for visiting this node.
        /// </summary>
        /// <param name="visitor">The visitor to accept.</param>
        /// <remarks>This method is part of the visitor design pattern implementation.</remarks>
        protected override void AcceptCore(AstVisitor visitor)
        {
            if (visitor.OnVisiting(this))
            {
                // Visit children
                if (this.ChildNodeCount > 0)
                    this.AcceptChildren(visitor, this.ChildNodes);
            }
            visitor.OnVisited(this);
        }

        /// <summary>
        /// Gets the <see cref="SimpleNodeType"/> that identifies the type of node.
        /// </summary>
        /// <value>The <see cref="SimpleNodeType"/> that identifies the type of node.</value>
        public override SimpleNodeType NodeType
        {
            get
            {
                return SimpleNodeType.CompilationUnit;
            }
        }

        /// <summary>
        /// Gets the collection of functions.
        /// </summary>
        /// <value>The collection of statements.</value>
        public IAstNodeList Functions
        {
            get
            {
                return new AstNodeListWrapper(this, CompilationUnit.FunctionContextID);
            }
        }

        /// <summary>
        /// Gets or sets the string-based key that identifies the source of the code, which typically is a filename.
        /// </summary>
        /// <value>The string-based key that identifies the source of the code, which typically is a filename.</value>
        public System.String SourceKey
        {
            get
            {
                return sourceKey;
            }
            set
            {
                sourceKey = value;
            }
        }

        /// <summary>
        /// Returns whether an <see cref="CollapsibleNodeOutliningParser"/> should visit the child nodes of the specified <see cref="IAstNode"/>
        /// to look for collapsible nodes.
        /// </summary>
        /// <param name="node">The <see cref="IAstNode"/> to examine.</param>
        /// <returns>
        /// <c>true</c> if the child nodes should be visited; otherwise, <c>false</c>.
        /// </returns>
        bool ICompilationUnit.ShouldVisitChildNodesForOutlining(IAstNode node)
        {
            return true;
        }

        /// <summary>
        /// Adds any extra <see cref="CollapsibleNodeOutliningParserData"/> nodes to the <see cref="CollapsibleNodeOutliningParser"/>,
        /// such as for comments that should be marked as collapsible.
        /// </summary>
        /// <param name="outliningParser">The <see cref="CollapsibleNodeOutliningParser"/> to update.</param>
        void ICompilationUnit.UpdateOutliningParser(CollapsibleNodeOutliningParser outliningParser)
        {
        }

        /// <summary>
        /// Gets whether the compilation unit contains errors.
        /// </summary>
        /// <value>
        /// <c>true</c> if the compilation unit contains errors.
        /// </value>
        public bool HasErrors
        {
            get
            {
                return ((syntaxErrors != null) && (syntaxErrors.Count > 0));
            }
        }

        /// <summary>
        /// Gets or sets whether the compilation unit contains any language transitions.
        /// </summary>
        /// <value>
        /// <c>true</c> if the compilation unit contains any language transitions; otherwise, <c>false</c>.
        /// </value>
        public bool HasLanguageTransitions
        {
            get
            {
                return hasLanguageTransitions;
            }
            set
            {
                hasLanguageTransitions = value;
            }
        }

        /// <summary>
        /// Gets whether the AST node is a language root node.
        /// </summary>
        /// <value>
        /// <c>true</c> if the AST node is a language root node; otherwise, <c>false</c>.
        /// </value>
        /// <remarks>
        /// When in a scenario where AST node trees from multiple languages have been merged together,
        /// it is useful to identify where child language AST node trees begin within their parents.
        /// </remarks>
        public override bool IsLanguageRoot
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Gets the collection of syntax errors that were found in the compilation unit.
        /// </summary>
        /// <value>The collection of syntax errors that were found in the compilation unit.</value>
        public IList SyntaxErrors
        {
            get
            {
                if (syntaxErrors == null)
                    syntaxErrors = new ArrayList();

                return syntaxErrors;
            }
        }

    }

}
